home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / BORLAND TURBO / 32SNIPIT.PAK / TRANSACT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  10.7 KB  |  302 lines

  1. // BDE32 3.x - (C) Copyright 1996 by Borland International
  2.  
  3. // transact.c
  4. #include "snipit.h"
  5.  
  6. static pCHAR SQLTblName = "SQLTran";
  7.  
  8. // Field descriptor used in creating a table
  9. static FLDDesc FldDesc =
  10.                           { // Field 1 - First Name
  11.                             1,              // Field number
  12.                             "Name",         // Field name
  13.                             fldZSTRING,     // Field type
  14.                             fldUNKNOWN,     // Field subtype
  15.                             10,             // Field size ( 1 or 0, except
  16.                                             //     BLOb or CHAR field )
  17.                             0,              // Decimal places ( 0 )
  18.                                             //     computed
  19.                             0,              // Offset in record ( 0 )
  20.                             0,              // Length in bytes  ( 0 )
  21.                             0,              // For Null bits    ( 0 )
  22.                             fldvNOCHECKS,   // Validity checks   ( 0 )
  23.                             fldrREADWRITE   // Rights
  24.                           };
  25.  
  26. // Index descriptor - describes the index associated with the table.
  27. static IDXDesc IdxDesc =
  28.                     {
  29.                         { "BaseIdx" },      // Name
  30.                         1,                  // Number
  31.                         { NULL },           // Tag name (dBASE only)
  32.                         { NULL },           // Optional format
  33.                         FALSE,              // Primary?
  34.                         TRUE,               // Unique?
  35.                         FALSE,              // Descending?
  36.                         TRUE,               // Maintained?
  37.                         FALSE,              // SubSet?
  38.                         FALSE,              // Expression index?
  39.                         NULL,               // for QBE only
  40.                         1,                  // Fields in key
  41.                         NULL,               // Length in bytes
  42.                         FALSE,              // Index out of date?
  43.                         0,                  // Key type of expression
  44.                         { 1 },              // Array of field numbers
  45.                         { NULL },           // Key expression
  46.                         { NULL },           // Key condition
  47.                         FALSE,              // Case insensitive
  48.                         0,                  // Block size in bytes
  49.                         0                   // Restructure number
  50.                     };
  51.  
  52. // Function prototypes
  53. static DBIResult CreateAndOpenSQLTable(hDBIDb hDb, phDBICur phTbl,
  54.                                        pCHAR pTblName, pCHAR pTblType);
  55. static DBIResult AddTranRecord(hDBICur hCur, pCHAR pStr);
  56.  
  57. //=====================================================================
  58. //  Function:
  59. //          SQLTran();
  60. //
  61. //  Description:
  62. //          This example will describe how to begin a transaction,
  63. //          verify that the transaction is still active, and commit
  64. //          (or rollback) the transaction based on its state.
  65. //
  66. //  WARNING: This example requires write access to the SQL server.
  67. //=====================================================================
  68. void
  69. SQLTran (void)
  70. {
  71.     hDBIDb      hDb;        // Handle to the database.
  72.     hDBICur     hCur;       // Handle to the table.
  73.     hDBIXact    hTran;      // Handle to the transaction.
  74.     XInfo       TranInfo;   // Information about the transaction.
  75.     pCHAR       pTblType;   // Buffer to contain the type of the table.
  76.     DBIResult   rslt;       // Return value from IDAPI functions
  77.     eXEnd       TranAct;    // Transaction action to take:  commit or
  78.                             //   rollback. 
  79.     UINT16      uLength;    // Length of property returned from DbiGetProp
  80.  
  81.     Screen("*** SQL Transaction Example ***\r\n");
  82.  
  83.     BREAK_IN_DEBUGGER();
  84.  
  85.     Screen("    Initializing IDAPI...");
  86.     if (InitAndConnect2(&hDb) != DBIERR_NONE)
  87.     {                                         
  88.         Screen("\r\n*** End of Example ***");
  89.         return;
  90.     }
  91.  
  92.     // Get the database type
  93.     pTblType = (pCHAR)malloc(DBIMAXNAMELEN + 1);
  94.  
  95.     rslt = DbiGetProp(hDb, dbDATABASETYPE, pTblType, sizeof(DBINAME),
  96.                       &uLength);
  97.     ChkRslt(rslt, "GetProp");
  98.  
  99.     // Verify that the selected database is a remote SQL server: this
  100.     // example only works with remote SQL databases such as Interbase
  101.     // and Oracle.
  102.     if (! strcmp(pTblType, "STANDARD"))
  103.     {
  104.         Screen("This example only works on remote SQL"
  105.                " databases.");
  106.         free(pTblType);
  107.         CloseDbAndExit(&hDb);
  108.         Screen("\r\n*** End of Example ***");
  109.         return;
  110.     }
  111.  
  112.     // Create a sample table and insert records.
  113.     if (CreateAndOpenSQLTable(hDb, &hCur, SQLTblName, pTblType)
  114.         != DBIERR_NONE)
  115.     {
  116.         free(pTblType);
  117.         CloseDbAndExit(&hDb);
  118.         Screen("\r\n*** End of Example ***");
  119.         return;
  120.     }
  121.  
  122.     Screen("\r\n    The table before the transaction...");
  123.  
  124.     rslt = DbiSetToBegin(hCur);
  125.     ChkRslt(rslt, "SetToBegin");
  126.     DisplayTable(hCur, 0);
  127.  
  128.     // Start a transaction with a READCOMMIT isolation level
  129.     rslt = DbiBeginTran(hDb, xilREADCOMMITTED, &hTran);
  130.     if (ChkRslt(rslt, "BeginTran") == DBIERR_NONE)
  131.     {
  132.         // Set the default to commit the transaction.  Rollback only if
  133.         //   an error occurs.
  134.         TranAct = xendCOMMIT;
  135.  
  136.         // Verify the state of the transaction
  137.         rslt = DbiGetTranInfo(hDb, hTran, &TranInfo);
  138.         ChkRslt(rslt, "GetTranInfo");
  139.  
  140.         if (TranInfo.exState != xsACTIVE)
  141.         {
  142.             Screen("    Error - Transaction is not active");
  143.         }
  144.         else
  145.         {
  146.             // Transaction is usable.  Add some data!
  147.             Screen("\r\n    Inserting two new records...");
  148.             rslt = AddTranRecord(hCur, "Angela");
  149.             if (rslt != DBIERR_NONE)
  150.             {
  151.                 // Rollback the transaction if the insert failed
  152.                 TranAct = xendABORT;
  153.             }
  154.             rslt = AddTranRecord(hCur, "Bernice");
  155.             if (rslt != DBIERR_NONE)
  156.             {
  157.                 // Rollback the transaction if the insert failed
  158.                 TranAct = xendABORT;
  159.             }
  160.         }
  161.  
  162.         // End the transaction (committing changes), then reread the
  163.         // table (updates the cache).
  164.         Screen("    Ending the transaction...");
  165.         rslt = DbiEndTran(hDb, hTran, TranAct);
  166.         ChkRslt(rslt, "EndTran");
  167.  
  168.         // Note: The call to DbiForceReread is only required in 
  169.         // a multi-user environment when we need to guarantee the
  170.         // concurrency of data.
  171.         rslt = DbiForceReread(hCur);
  172.         ChkRslt(rslt, "ForceReread");
  173.  
  174.         Screen("\r\n    The table after the transaction...");
  175.         rslt = DbiSetToBegin(hCur);
  176.         ChkRslt(rslt, "SetToBegin");
  177.         DisplayTable(hCur, 0);
  178.     }
  179.  
  180.     rslt = DbiCloseCursor(&hCur);
  181.     ChkRslt(rslt, "CloseCursor");
  182.  
  183.     // Cleanup.
  184.     Screen("\r\n    Delete the table from the server...");
  185.     rslt = DbiDeleteTable(hDb, SQLTblName, pTblType);
  186.     ChkRslt(rslt, "DeleteTable");
  187.  
  188.     Screen("    Close the database and exit IDAPI...");
  189.     CloseDbAndExit(&hDb);
  190.  
  191.     free(pTblType);
  192.  
  193.     Screen("\r\n*** End of Example ***");
  194. }
  195.  
  196. //=====================================================================
  197. //  Function:
  198. //          CreateSQLTable(hDb, phCur, pTblName, pTblType);
  199. //
  200. //  Input:  phDb        - Pointer to the database handle.
  201. //          phCur       - Cursor to the table.
  202. //          pTblName    - The name of the table to create.
  203. //          pTblType    - The type of table.
  204. //
  205. //  Return: Result returned by IDAPI.
  206. //
  207. //  Description:
  208. //          This will try to create a table on the SQL server. It will
  209. //          also insert a few records.
  210. //
  211. //  Note:   This example will not work on local tables.
  212. //=====================================================================
  213. DBIResult
  214. CreateAndOpenSQLTable (hDBIDb hDb, phDBICur phCur, pCHAR pTblName,
  215.                        pCHAR pTblType)
  216. {
  217.     DBIResult   rslt;          // Value returned from IDAPI functions
  218.     CRTblDesc   crTblDsc;      // Table descriptor
  219.  
  220.     // Initialize the create table descriptor
  221.     memset(&crTblDsc, 0, sizeof(CRTblDesc));
  222.     strcpy(crTblDsc.szTblName, pTblName) ;
  223.     strcpy(crTblDsc.szTblType, pTblType) ;
  224.     crTblDsc.iFldCount     = 1;
  225.     crTblDsc.pfldDesc      = &FldDesc ;
  226.     crTblDsc.iIdxCount     = 1;
  227.     crTblDsc.pidxDesc      = &IdxDesc ;
  228.  
  229.     Screen("    Creating the table...");
  230.     rslt = DbiCreateTable(hDb, TRUE, &crTblDsc);
  231.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  232.     {
  233.         return rslt;
  234.     }
  235.  
  236.     rslt = DbiOpenTable(hDb, pTblName, pTblType,
  237.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  238.                         xltFIELD, FALSE, NULL, phCur);
  239.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  240.     {
  241.         rslt = DbiDeleteTable(hDb, pTblName, pTblType);
  242.         ChkRslt(rslt, "DeleteTable");
  243.         return rslt;
  244.     }
  245.  
  246.     // Add records to the table
  247.     Screen("    Adding records to the table...");
  248.     AddTranRecord(*phCur, "Tom");
  249.     AddTranRecord(*phCur, "Jim");
  250.     rslt = AddTranRecord(*phCur, "Larry");
  251.  
  252.     // The table handle is returned to the calling function in the phCur
  253.     // parameter.
  254.     return rslt;
  255. }
  256.  
  257. //=====================================================================
  258. //  Function:
  259. //          AddTranRecord(hCur, pStr);
  260. //
  261. //  Input:  hCur - The table handle
  262. //          pStr - The data to insert
  263. //
  264. //  Return: Result of adding the record to the table
  265. //
  266. //  Description:
  267. //          Insert a record into the table.
  268. //=====================================================================
  269. DBIResult
  270. AddTranRecord (hDBICur hCur, pCHAR pStr)
  271. {
  272.     DBIResult   rslt;       // Value returned from IDAPI functions.
  273.     pBYTE       pRecBuf;    // Record buffer.
  274.     CURProps    TblProps;   // Table properties.
  275.  
  276.     //  Allocate a record buffer.
  277.     rslt = DbiGetCursorProps(hCur, &TblProps);
  278.     ChkRslt(rslt, "GetCursorProps");
  279.  
  280.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
  281.     if (pRecBuf == NULL)
  282.     {
  283.         Screen("    Error - Out of memory");
  284.         return DBIERR_NOMEMORY;
  285.     }
  286.  
  287.     // Clear the record buffer, then add the data.
  288.     rslt = DbiInitRecord(hCur, pRecBuf);
  289.     ChkRslt(rslt, "InitRecord");
  290.  
  291.     rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pStr);
  292.     ChkRslt(rslt, "PutField");
  293.  
  294.     rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
  295.     ChkRslt(rslt, "InsertRecord");
  296.  
  297.     free(pRecBuf);
  298.  
  299.     return rslt;
  300. }
  301.  
  302.